home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
misc
/
jlem
/
progjlem.pas
< prev
Wrap
Pascal/Delphi Source File
|
1992-12-10
|
22KB
|
555 lines
{**********************************************************************}
{ }
{ PROGRAM NAME: JLEM }
{ WRITTEN BY: JOHN NEMEC }
{ DATE: OCTOBER 1992 }
{ }
{ This PASCAL program reads an Intel hex file and sends data to the }
{ ROM EMULATOR in serial format. }
{ }
{ You can quit JLEM and unplug the emulator from the PC. The emulator }
{ will remain in the EMULATE mode and the target system will continue }
{ to run. }
{ }
{**********************************************************************}
program LEM;
type hexstr = string[4];
{**********************************************************************}
{ }
{ FUNCTION NCON }
{ }
{ Converts a string representing a hexadecimal number to the number }
{ }
{**********************************************************************}
function ncon(hexnum: hexstr): integer;
{**********************************************************************}
{ }
{ FUNCTION NUMBER }
{ }
{ Converts an ASCII character representing a hex number into an integer}
{ }
{**********************************************************************}
function number(hexchr: char): integer;
var temp: integer;
begin
hexchr := UpCase(hexchr);
temp := Ord(hexchr) - 48;
if (temp > 16) then begin
temp := temp - 7;
if (temp < 10) then temp := temp -10;
end;
if (temp > 15) then temp := -temp;
number := temp;
end;
var i,t,sum,l: integer;
begin
l := length(hexnum);
t := 1;
sum := 0;
for i := 1 to l do begin
sum := sum + t*number(hexnum[l - i + 1]);
t := t*16;
end;
ncon := sum;
end;
{ }
{**********************************************************************}
{ }
type name = string[80];
memarray = array[0..2047] of byte;
{**********************************************************************}
{ }
{ PROCEDURE INTELREAD }
{ }
{ Reads the object code file in "INTEL HEX FORMAT", processes the }
{ data, does basic checks on the data, changes the instruction code }
{ from HEX to binary and stores it in the memory array. }
{ }
{**********************************************************************}
procedure intelread(intelname: name; var mdata: memarray; var maxadr: integer);
var
Buffer: char;
intelfile: file of char;
reclength: string[2];
addresst: string[4];
address, recint, i: integer;
label start, error, stop, cont;
{ }
{**********************************************************************}
{ }
{ OPEN THE FILE (USER ENTERS FILENAME) }
{ }
{**********************************************************************}
{ }
begin
maxadr := 0;
Assign(intelfile,intelname);
Reset(intelfile);
repeat
start:
{ }
{**********************************************************************}
{ }
{ READ RECORD MARK FIELD AND VERIFY CORRECT }
{ }
{**********************************************************************}
{ }
Read(intelfile,Buffer);
if (Buffer = ':') then goto cont;
for i := 1 to 3 do begin
Read(intelfile,Buffer);
if (Buffer = ':') then goto cont;
end;
writeln('no :');
halt;
{ }
{**********************************************************************}
{ }
{ READ RECORD LENGTH FIELD AND CONVERT TO INTEGER }
{ }
{**********************************************************************}
{ }
cont:
reclength := '';
Read(intelfile,Buffer);
reclength := reclength + Buffer;
Read(intelfile,Buffer);
reclength := reclength + Buffer;
recint := ncon(reclength);
if (recint = 0) then goto stop;
{ }
{**********************************************************************}
{ }
{ READ ADDRESS FIELD AND CONVERT TO INTEGER }
{ }
{**********************************************************************}
{ }
addresst := '';
Read(intelfile,Buffer);
addresst := addresst + Buffer;
Read(intelfile,Buffer);
addresst := addresst + Buffer;
Read(intelfile,Buffer);
addresst := addresst + Buffer;
Read(intelfile,Buffer);
addresst := addresst + Buffer;
address := ncon(addresst);
{ }
{**********************************************************************}
{ }
{ READ RECORD TYPE FIELD }
{ }
{**********************************************************************}
{ }
reclength := '';
Read(intelfile,Buffer);
reclength := reclength + Buffer;
Read(intelfile,Buffer);
reclength := reclength + Buffer;
if (reclength <> '00') then goto stop;
{ }
{**********************************************************************}
{ }
{ READ DATA FIELDS; REPEAT RECINT TIMES }
{ }
{**********************************************************************}
{ }
for i := 1 to recint do begin
reclength := '';
Read(intelfile,Buffer);
reclength := reclength + Buffer;
Read(intelfile,Buffer);
reclength := reclength + Buffer;
mdata[address + i -1] := ncon(reclength);
if ((address + i - 1) > maxadr) then maxadr := address + i - 1;
end;
{ }
{**********************************************************************}
{ }
{ READ CHECKSUM FIELD }
{ }
{**********************************************************************}
{ }
reclength := '';
Read(intelfile,Buffer);
reclength := reclength + Buffer;
Read(intelfile,Buffer);
reclength := reclength + Buffer;
until EOF(intelfile);
stop:
Close(intelfile);
end;
{ }
{**********************************************************************}
{ }
{ TIME DELAY PROCEDURE }
{ }
{**********************************************************************}
{ }
procedure tdly(n:integer);
var i:integer;
begin
for i := 1 to n do;
end;
const td: integer = 10;
procedure init;
{ }
{**********************************************************************}
{ }
{ PUT THE SIMULATOR INTO THE LEARN MODE }
{ OUTPUT DATA TO PRINTER PORT 1 IN SERIAL MODE }
{ }
{**********************************************************************}
{ }
var
i: integer;
begin
port[634] := $20;
port[632] := 2; {DUMMY DATA TO PUT FLIP FLOP IN LEARN MODE}
tdly(td);
port[634] := $21;
tdly(td);
port[634] := $20;
tdly(td);
port[632] := 3;
tdly(td);
for i := 1 to 23 do begin
port[634] := $21;
tdly(td);
port[634] := $20;
tdly(td);
end;
port[632] := 0; {set control low -- CLOCK LEARN/EMULATE FLIP FLOP}
tdly(td);
port[634] := $21;
tdly(td);
port[634] := $20;
tdly(td);
port[632] := 2;
end;
procedure endload;
{ }
{**********************************************************************}
{ }
{ PUT THE SIMULATOR IN THE EMULATE MODE }
{ USE DUMMY DATA; DON'T WRITE TO RAM BUT PUT 1 }
{ INTO FLIP FLOP TO PUT INTO EMULATE MODE }
{ }
{**********************************************************************}
{ }
var
i: integer;
begin
port[632] := 3;
tdly(td);
for i := 1 to 24 do begin
port[634] := $21;
tdly(td);
port[634] := $20;
tdly(td);
end;
port[632] := 0; {set control low}
tdly(td);
port[634] := $21;
tdly(td);
port[634] := $20;
tdly(td);
port[632] := 2;
end;
{ }
{**********************************************************************}
{ }
{ PROCEDURE LOADBYTE }
{ Loads a byte of data into the memory at a specified address }
{ }
{**********************************************************************}
{ }
procedure loadbyte(data: byte; address: integer);
var
adrcont, i: integer;
out: byte;
begin
{ }
{**********************************************************************}
{ }
{ Bit 0 of port [634] is clock (STROBE) }
{ Bit 0 of port [632] is data and bit 1 is control }
{ }
{**********************************************************************}
{ }
adrcont := address AND $0FFF;
for i := 15 downto 0 do begin
out := $02 OR ((adrcont SHR i) AND $01); {SERIALIZES INTEGER ADDRESS}
port[632] := out;
port[634] := $21;
tdly(td);
port[634] := $20;
end;
for i := 7 downto 0 do begin
out := $02 OR ((data SHR i) AND $01); {SERIALIZES BYTE (INSTRUCTION)}
port[632] := out;
port[634] := $21;
tdly(td);
port[634] := $20;
end;
port[632] := 0; {SET CONTROL LOW}
tdly(td);
port[634] := $21; {STROBE INTO MEMORY}
tdly(td);
port[634] := $20;
tdly(td);
port[632] := 2;
end;
{ }
{**********************************************************************}
{ }
{ FUNCTION TEST }
{ Test to see if HEXNUM is valid hexadecimal number }
{ Lower case is assumed }
{ }
{**********************************************************************}
{ }
function test(hexnum: hexstr): boolean;
var i: integer;
temp,temp1: boolean;
tempch: char;
begin
temp1 := TRUE;
for i := 1 to length(hexnum) do begin
tempch := UpCase(hexnum[i]);
case tempch of
'0': temp := TRUE;
'1': temp := TRUE;
'2': temp := TRUE;
'3': temp := TRUE;
'4': temp := TRUE;
'5': temp := TRUE;
'6': temp := TRUE;
'7': temp := TRUE;
'8': temp := TRUE;
'9': temp := TRUE;
'A': temp := TRUE;
'B': temp := TRUE;
'C': temp := TRUE;
'D': temp := TRUE;
'E': temp := TRUE;
'F': temp := TRUE;
else temp := FALSE;
end;
temp1 := temp1 AND temp;
test := temp1;
end;
end;
{ }
{**********************************************************************}
{ }
{ PROCEDURE HEXCHG }
{ Converts a number into the HEX representation as a string }
{ }
{**********************************************************************}
{ }
procedure hexchg(numin: integer; var hexnum: hexstr);
{converts a number into the Hex representation as a string}
var ch: string[1];
temp,i: integer;
begin
hexnum := '';
for i := 4 downto 1 do begin
temp := (numin SHR (4*(i-1)) AND $000F);
if (temp > 9) then temp := temp + 55 else temp := temp + 48;
ch := Chr(temp);
hexnum := hexnum + ch;
end;
end;
{ }
{**********************************************************************}
{ }
{ MAIN PROGRAM BEGINS HERE }
{ }
{**********************************************************************}
{ }
var
address, times, maxadr: integer;
memory: memarray;
cmd: char;
hadr,prhex,memhex: hexstr;
fname: name;
label input1, input2, cycle1, cycle2, reread, reload, command;
begin
LowVideo;
for address := 0 to 2047 do memory[address] := 0;
write('Enter Intel hex code file name: ');
readln(fname);
if (Pos('.',fname) = 0) then fname := fname + '.hex';
intelread(fname,memory,maxadr);
reload:
init;
if (maxadr > 2047) then writeln('Warning program exceeds simulator memory.');
writeln('Loading Simulator Module.');
{ }
{**********************************************************************}
{ }
{ CALL "LOADBYTE" TO SEND BYTE AT A TIME WITH ADDRESS }
{ }
{**********************************************************************}
{ }
for address := 0 to maxadr do loadbyte(memory[address],address);
endload; {PUT IN EMULATE MODE}
writeln('Simulation mode.');
command: writeln;
read(KBD, cmd); {ACCEPT USER COMMAND}
cmd := UpCase(cmd);
case cmd of
'D': goto input2; {"D"ISPLAY MEMORY CONTENTS IN HEX ON SCREEN}
'C': goto input1; {"C"HANGE A BYTE}
'R': goto reload; {"R"ELOAD ENTIRE EMULATION RAM}
'Q': halt; {"Q"UIT -- RETURN TO DOS}
else goto command;
end;
{ }
{**********************************************************************}
{ }
{ CHANGE MEMORY }
{ }
{**********************************************************************}
{ }
input1: write('C: ');
readln(hadr);
if (NOT test(hadr)) then goto input1;
address := ncon(hadr);
cycle1: hexchg(address, prhex);
hexchg(memory[address], memhex);
Delete(memhex, 1,2);
write(prhex,': ',memhex,' ');
reread:
read(KBD, cmd);
{ }
{**********************************************************************}
{ }
{ IF "SPACEBAR" IS PRESSED DON'T CHANGE; INCR ADDRESS }
{ }
{**********************************************************************}
{ }
if (cmd = '') then begin
address := address + 1;
writeln;
goto cycle1;
end;
if (cmd = #13) then goto command;
write(cmd);
readln(memhex); {ENTER NEW BYTE TO BE PLACED AT ADDRESS}
memhex := cmd + memhex;
if ((NOT test(memhex)) OR (Length(memhex) > 2)) then goto reread;
memory[address] := ncon(memhex);
init; {PUT IN LEARN MODE}
loadbyte(memory[address], address); {SEND ADDRESS & BYTE}
endload; {PUT IN EMULATE MODE}
hexchg(memory[address], memhex);
Delete(memhex, 1,2);
writeln(prhex,': ',memhex,' ');
if (address < 2047) then address := address +1 else address :=0;
goto cycle1;
goto command;
{ }
{**********************************************************************}
{ }
{ DISPLAY MEMORY }
{ Converts MEMARRAY into HEX so you can read it and puts it on the }
{ screen. }
{ }
{**********************************************************************}
{ }
input2: write('D: ');
readln(hadr);
if (NOT test(hadr)) then goto input2;
address := ncon(hadr);
times := 0;
cycle2: times := times + 1;
hexchg(address, prhex);
hexchg(memory[address], memhex);
Delete(memhex, 1,2);
write(prhex,': ',memhex,' ');
if ((address < 2046) AND (times < 128)) then begin
address := address + 1;
goto cycle2;
end;
writeln;
goto command;
end.